<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <!-- 
      监听器
        是一个通过 watch 选项声明的内容
      
      能干什么：
        让我们监听数据的变化之后，去干一些额外的逻辑。

      监听器默认触发一次
        可以将 value 写成 对象的形式，然后处理函数通过 handler 配置项来编写，再添加一个  immediate: true 让监听函数默认触发一次

      深度监听
        可以通过配置 deep: true 开启深度监听
        PS: 少用
          1. 如果我们只是需要监听 person.name ，当 person.age 的变化也会触发监听的处理函数，没有必要。

      监听的key可以写成对象的点语法
        'person.name'() {
          
        },

        'person.age'() {

        }

      通过 实例方法 $watch 来开启监听
        语法：
          const unwatch = this.$watch(要监听的数据源, 处理函数 | 处理对象)
          unwatch是移除监听的函数，调用它就能取消监听
        
      watch 与 computed 的区别：
        1. 概念不同：
          computed 是基于现有数据通过计算得到一份新的数据来使用。
          watch 是监听数据的变化，来做一些额外的逻辑。
        2. 能否处理异步
          computed 不能写异步代码
          watch 可以写异步代码
        3. computed 必须有返回值，watch 不需要
     -->

    <div id="app">
      <button @click="firstName = firstName + '~'">{{ firstName }}</button>
      <button @click="lastName = lastName + '~'">{{ lastName }}</button>

      <button @click="person.name = person.name + '！'">
        {{ person.name }}
      </button>
      <button @click="person.age++">{{ person.age }}</button>

      <button @click="start">start</button>
      <button @click="end">end</button>
    </div>

    <script src="../lib/vue.js"></script>
    <script>
      const vm = new Vue({
        el: "#app",
        // 状态数据、响应式数据
        data: {
          firstName: "张",
          lastName: "三",
          fruits: [
            { id: 1, name: "苹果" },
            { id: 2, name: "香蕉" },
          ],
          person: {
            name: "张三",
            age: 18,
          },
        },

        computed: {
          fullName() {
            setTimeout(() => {
              return this.firstName + " " + this.lastName;
            }, 1000);
          },
        },

        watch: {
          // key - 要监听的数据源
          // value - 一个处理函数, 能接受到 newValue 与 oldValue 两个参数
          // firstName(newValue, oldValue) {
          //   console.log("firstName 改变了", newValue, oldValue);
          // },

          firstName: {
            handler(newValue, oldValue) {
              console.log("firstName 改变了", newValue, oldValue);
            },

            immediate: true, // 默认触发一次
          },

          person: {
            handler() {
              console.log("person 改变了");
            },

            deep: true, // 开启深度监听
          },

          "person.name"() {
            console.log("person.name 改变了");
          },
        },

        methods: {
          start() {
            // 开启监听
            this.unWatch = this.$watch("lastName", function () {
              console.log("lastName 改变了");
            });
          },
          end() {
            // 取消监听
            this.unWatch();
          },
        },
      });
    </script>
  </body>
</html>
